from ...util.event import EmitterGroup

from ._multi import MultiIndexList
from ._typed import TypedList


class ListModel(MultiIndexList, TypedList):
    """List with events, tuple-indexing, typing, and filtering.
    
    Parameters
    ----------
    basetype : type
        Type of the elements in the list.
    iterable : iterable, optional
        Elements to initialize the list with.
    lookup : dict of type : function(object, ``basetype``) -> bool
        Functions that determine if an object is a reference to an
        element of the list.

    Attributes
    ----------
    changed : vispy.util.event.EmitterGroup
        Group of events for adding, removing, and reordering elements
        within the list.
    """
    def __init__(self, basetype, iterable=(), lookup=None):
        super().__init__(basetype, iterable, lookup)
        self.changed = EmitterGroup(source=self,
                                    auto_connect=True,
                                    added=None,
                                    removed=None,
                                    reordered=None)

    def __setitem__(self, query, values):
        indices = tuple(self.__prsitem__(query))
        new_indices = tuple(values)

        if sorted(indices) != sorted(self.index(v) for v in new_indices):
            raise TypeError('must be a reordering of indices; '
                            'setting of list items not allowed')

        super().__setitem__(indices, new_indices)
        self.changed.reordered()

    def insert(self, index, object):
        super().insert(index, object)
        self.changed.added(item=object, index=self.__locitem__(index))

    def append(self, object):
        super(TypedList, self).append(object)
        self.changed.added(item=object, index=len(self) - 1)

    def pop(self, key):
        obj = super().pop(key)
        self.changed.removed(item=obj)
        return obj
